package gupao.concurrency.threads;

import sun.misc.Unsafe;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

//无法运行: Unsafe.getUnsafe() 会判断当前是否是systemClassLoader
public class CasSample2 {
    public static void main(String[] args) throws InterruptedException {
        CasCounter counter = new CasCounter();

        List<Thread> threadList = IntStream.range(0, 10).mapToObj(i -> new Thread(() -> {
            for (int k = 0; k < 1000; k++) {
                counter.safeCount();
                Utils.waitNanos(1000);
            }
        }, "count-thread-" + i)).collect(Collectors.toList());

        threadList.forEach(t -> t.start());
        for (Thread t : threadList) {
            t.join();
        }

        System.out.println("Complete all threads ");
        System.out.println("count: " + counter.val);
    }

    static class CasCounter {
        private static final Unsafe unsafe = Unsafe.getUnsafe();
        private int val;
        private static final long valOffset;

        static {
            try {
                valOffset = unsafe.objectFieldOffset
                        (AtomicInteger.class.getDeclaredField("val"));
            } catch (Exception ex) {
                throw new Error(ex);
            }
        }

        private boolean compareAndSet(int expect, int update) {
            return unsafe.compareAndSwapInt(this, valOffset, expect, update);
        }

        public void unsafeCount() {
            val++;
        }

        public void safeCount() {
            int tmp;
            do {
               tmp = unsafe.getIntVolatile(this, valOffset);
            } while (!unsafe.compareAndSwapInt(this, valOffset, tmp, tmp+1));
        }
    }
}
